/*
 * @Copyright: 2016 www.yyfax.com Inc. All rights reserved.
 */
package com.yyfax.pay.order.controller.api;

import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.yyfax.framework.common.OpResponse;
import com.yyfax.framework.exception.YYException;
import com.yyfax.framework.model.EmptyContent;
import com.yyfax.framework.model.YYFaxRsp;
import com.yyfax.framework.yyfax.enums.RspCodeEnum;
import com.yyfax.pay.common.annotation.CheckSign;
import com.yyfax.pay.common.enums.PayRspCodeEnum;
import com.yyfax.pay.common.model.to.YYPayApiReq;
import com.yyfax.pay.common.model.to.YYPayApiReq2;
import com.yyfax.pay.config.data.service.MerchantConfigService;
import com.yyfax.pay.config.model.po.MerchantConfigPO;
import com.yyfax.pay.order.model.po.PayoutOrderLogPO;
import com.yyfax.pay.order.model.to.PayoutBatchOrderParams;
import com.yyfax.pay.order.model.to.PayoutOrderContent;
import com.yyfax.pay.order.model.to.PayoutOrderParams;
import com.yyfax.pay.order.model.to.QueryPayoutBatchOrderContent;
import com.yyfax.pay.order.model.to.QueryPayoutBatchOrderContent.QueryPayoutOrder;
import com.yyfax.pay.order.model.to.QueryPayoutBatchOrderParams;
import com.yyfax.pay.order.model.to.QueryPayoutOrderContent;
import com.yyfax.pay.order.model.to.QueryPayoutOrderParams;
import com.yyfax.pay.order.model.vo.PayoutBatchOrderVO;
import com.yyfax.pay.order.model.vo.PayoutOrderVO;
import com.yyfax.pay.order.service.PayoutService;

/**
 * 代付api入口
 * 
 * @author buyi
 * @date 2017-04-18 14:32:51
 * @since v1.0.0
 */
@RestController
public class PayoutApiController {
	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private MerchantConfigService merchantConfigService;

	@Autowired
	private PayoutService payoutService;

	/**
	 * 代付下单入口
	 * 
	 * @author buyi
	 * @date 2017-04-18 09:04:14
	 * @since v1.0.0
	 * @param req
	 * @return
	 * @throws Throwable
	 */
	@CheckSign
	@RequestMapping(method = RequestMethod.POST, path = "/api/payout/order")
	public YYFaxRsp<EmptyContent> payoutOrder(@RequestBody @Valid YYPayApiReq2<PayoutOrderParams> req) throws Throwable {
		PayoutOrderParams params = req.getParams();
		params.validate();

		// 3. 持久化代付订单
		PayoutOrderVO payoutOrderVO = payoutService.savePayoutOrder(req.getMerchantCode(), params);

		// 4.订单幂等操作
		// 新版本新增state字段，edit by buyi since 2.1.4
		// PayoutOrderLogPO lastResultStep = payoutOrderVO.getOrderLastResultStep();
		// if (lastResultStep != null && !PayRspCodeEnum.PAY_CODE_REQ_TIME_OUT.isValue(lastResultStep.getResultCode())) {
		//
		// return new YYFaxRsp<EmptyContent>(lastResultStep.getResultCode(), lastResultStep.getResultMsg(),lastResultStep.getResultMsg(), null);
		// }
		if (payoutOrderVO.isResult()) {
			return new YYFaxRsp<EmptyContent>(payoutOrderVO.getRspCode(), payoutOrderVO.getRspMsg(), payoutOrderVO.getRspMsg(), null);
		}

		// 兼容旧版本没有state的场景
		if (StringUtils.isBlank(payoutOrderVO.getState())) {
			// 如果状态为空，则表示是旧版本代付数据
			PayoutOrderLogPO lastResultStep = payoutOrderVO.getOrderLastResultStep();
			if (lastResultStep != null) {
				return new YYFaxRsp<EmptyContent>(lastResultStep.getResultCode(), lastResultStep.getResultMsg(), lastResultStep.getResultMsg(), null);
			}
		}

		// 如果订单未出结果，则发起代付请求
		PayoutOrderContent content = payoutService.payout(payoutOrderVO);

		return new YYFaxRsp<EmptyContent>(content.getResultCode(), content.getResultMsg(), content.getResultMsg(), null);
	}

	/**
	 * 批量代付入口
	 * 
	 * @author buyi
	 * @date 2017-04-18 09:04:14
	 * @since v1.0.0
	 * @param req
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(method = RequestMethod.POST, path = "/api/payout/batch/order")
	public YYFaxRsp<PayoutOrderContent> payoutBatchOrder(@RequestBody YYPayApiReq<PayoutBatchOrderParams> req) throws Throwable {
		logger.debug("enter payout batch order ……");

		if (req == null || req.getParams() == null) {
			throw new YYException(RspCodeEnum.COMMON_ERROR_PARAMETER_INVALID);
		}

		PayoutBatchOrderParams params = req.getParams();

		// 1.校验参数
		params.validate();

		MerchantConfigPO merchantConfigPO = merchantConfigService.queryByMerchantCode(params.getMerchantCode());
		if (merchantConfigPO == null) {
			throw new YYException(PayRspCodeEnum.PAY_CODE_MERCHANT_NOT_EXISTS, "商户：" + params.getMerchantCode() + "信息不存在");
		}

		// 2.验签
		req.checkSign(merchantConfigPO.getSignKey());

		params.checkSign(merchantConfigPO.getSignKey());

		YYFaxRsp<PayoutOrderContent> payoutBatch = payoutService.payoutBatch(params);

		return payoutBatch;
	}

	/**
	 * 代付结果查询
	 *
	 * @author wujiande
	 * @date 2018/5/12 1:46
	 * @since v2.1.5
	 * @param req
	 * @return
	 * @throws Exception
	 */
	@CheckSign
	@RequestMapping(method = RequestMethod.POST, path = "/api/payout/query")
	public OpResponse payoutQuery(@RequestBody @Valid YYPayApiReq2<QueryPayoutOrderParams> req) throws Throwable {
		logger.debug("enter payout query order ……");

		if (req == null || req.getParams() == null) {
			throw new YYException(RspCodeEnum.COMMON_ERROR_PARAMETER_INVALID);
		}

		QueryPayoutOrderParams params = req.getParams();
		QueryPayoutOrderContent content = payoutService.queryPayoutOrder(params.getOrderId(), req.getMerchantCode());

		OpResponse response = OpResponse.success();
		response.setContent(content);
		return response;
	}

	/**
	 * 批量代付查询
	 * 
	 * @author buyi
	 * @date 2017-04-21 09:08:48
	 * @since v1.0.0
	 * @param req
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(method = RequestMethod.POST, path = "/api/payout/batch/query")
	public YYFaxRsp<QueryPayoutBatchOrderContent> payoutBatchQuery(@RequestBody YYPayApiReq<QueryPayoutBatchOrderParams> req) throws Throwable {
		logger.debug("enter payout batch order ……");

		if (req == null || req.getParams() == null) {
			throw new YYException(RspCodeEnum.COMMON_ERROR_PARAMETER_INVALID);
		}

		QueryPayoutBatchOrderParams params = req.getParams();

		// 1.校验参数
		params.validate();

		MerchantConfigPO merchantConfigPO = merchantConfigService.queryByMerchantCode(params.getMerchantCode());
		if (merchantConfigPO == null) {
			throw new YYException(PayRspCodeEnum.PAY_CODE_MERCHANT_NOT_EXISTS, "商户：" + params.getMerchantCode() + "信息不存在");
		}

		// 2.验签
		req.checkSign(merchantConfigPO.getSignKey());

		PayoutBatchOrderVO payoutBatchOrderVO = payoutService.queryPayoutBatchOrder(params.getOrderId(), params.getMerchantCode());

		QueryPayoutBatchOrderContent content = new QueryPayoutBatchOrderContent();
		BeanUtils.copyProperties(payoutBatchOrderVO, content);
		List<QueryPayoutOrder> dataList = new ArrayList<QueryPayoutOrder>();

		// 转换成响应参数
		List<PayoutOrderVO> payoutOrderVOs = payoutBatchOrderVO.getPayoutOrderVOs();
		if (payoutOrderVOs != null) {
			for (PayoutOrderVO payoutOrderVO : payoutOrderVOs) {
				QueryPayoutOrder queryPayoutOrder = new QueryPayoutOrder();
				BeanUtils.copyProperties(payoutOrderVO, queryPayoutOrder);

				dataList.add(queryPayoutOrder);
			}
		}

		return new YYFaxRsp<QueryPayoutBatchOrderContent>(PayRspCodeEnum.SUCCESS, content);
	}

}
